package cn.rkylin.oms.system.unit.dao;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Repository;

import cn.rkylin.core.IDataBaseFactory;
import cn.rkylin.core.exception.BusinessException;
import cn.rkylin.oms.common.event.EventBusManager;
import cn.rkylin.oms.system.unit.domain.WF_ORG_UNIT;
import cn.rkylin.oms.system.unit.domain.WF_ORG_USER_UNIT;
import cn.rkylin.oms.system.unit.event.AfterRBACChangedEvent;
import cn.rkylin.oms.system.user.domain.WF_ORG_USER;
/**
 * brief description
 * <p>
 * Date : 2010/05/05
 * </p>
 * <p>
 * Module : 组织机构管理
 * </p>
 * <p>
 * Description: 组织单元数据访问对象实现
 * </p>
 * 
 * @author 王潇艺
 */
@Repository(value = "unitDAO")
public class UnitDAOImpl implements IUnitDAO {
	@Autowired
	protected IDataBaseFactory dao;

	@SuppressWarnings("rawtypes")
	@Override
	public List getUnitByCondition(WF_ORG_UNIT unitParam) throws Exception {
        String statement="getUnitByCondition";
        List  result = null;
        String sql = null;
        try {
            List list = dao.findAllList(statement, unitParam);
            result = list;
        } catch (Exception e) {
            throw new BusinessException(e, "-20", ",index:" + statement + ",params:" + unitParam);
        }
        return result;
	}

//	@Override
//	@SuppressWarnings({ "rawtypes", "unchecked" })
//	public Map getExtInfo(String bizType, String idColumnValue) {
//		// 扩展表的表名
//		String extTableName = "";
//		// 扩展表的主键字段名
//		String idColumnName = "";
//		Connection conn = null;
//		Statement stmt = null;
//		Map returnMap = new HashMap();
//		Map temp = new HashMap();
//		try {
//			// 确定tableName和idColumnName
//			BizTypeDefine bizTypeDefine = OrgnizationConfig.getBizTypeDefine(bizType);
//			extTableName = bizTypeDefine.getTable();
//			if (bizTypeDefine.getElementList() != null || bizTypeDefine.getElementList().size() > 0) {
//				for (int j = 0; j < bizTypeDefine.getElementList().size(); j++) {
//					ElementDefine ed = (ElementDefine) bizTypeDefine.getElementList().get(j);
//					if (ed.getName().equalsIgnoreCase("id")) {
//						idColumnName = ed.getColumn();
//						break;
//					}
//				}
//			} else {
//				return new HashMap();
//			}
//
//			String selectSQL = "SELECT * FROM " + extTableName + " WHERE " + idColumnName + " = '" + idColumnValue
//					+ "'";
//			conn = sqlSession.getConfiguration().getEnvironment().getDataSource().getConnection();
//			stmt = conn.createStatement();
//			ResultSet rs = stmt.executeQuery(selectSQL);
//			if (rs.next()) {
//				for (int i = 1; i <= rs.getMetaData().getColumnCount(); i++) {
//					temp.put(rs.getMetaData().getColumnName(i), rs.getString(i));
//				}
//				if (bizTypeDefine.getElementList() != null || bizTypeDefine.getElementList().size() > 0) {
//					for (int j = 0; j < bizTypeDefine.getElementList().size(); j++) {
//						ElementDefine ed = (ElementDefine) bizTypeDefine.getElementList().get(j);
//						if (ed.getName().equalsIgnoreCase("id")) {
//							idColumnName = ed.getColumn();
//							continue;
//						}
//						returnMap.put(ed.getName(), temp.get(ed.getColumn()) == null ? "" : temp.get(ed.getColumn()));
//					}
//				}
//			}
//
//		} catch (SQLException e) {
//			e.printStackTrace();
//		} finally {
//			try {
//				if (stmt != null)
//					stmt.close();
//				if (conn != null)
//					conn.close();
//			} catch (Exception ex) {
//			}
//		}
//		return returnMap;
//	}
	
	/**
     * 方法简要描述信息.
     * <p>
     * 描述: 获取根组织，需要考虑当前组织，该用户是否能管理
     * </p>
     * <p>
     * 备注: 详见顺序图
     * </p>
     * 
     * @param userID
     *            - 用户id
     * @return 如果找到，返回JT_UNIT_TREE_V 如果没有找到，返回null
     * @throws SQLException
     * @throws Exception
     * @throws SQLException
     * @throws SQLException
     * @throws DataAccessException
     */
	@SuppressWarnings("rawtypes")
	@Override
	public List getRootUnit(String userId) throws Exception {
		return dao.findList("selectRootUnit", userId);
	}

	/**
     * 方法简要描述信息.
     * <p>
     * 描述: 获取某组织下的所有子组织，需要考虑当前组织，该用户是否能管理
     * </p>
     * <p>
     * 备注: 详见顺序图
     * </p>
     * 
     * @param userID
     *            - 用户id
     * @param parentUnitID
     *            - 父组织id
     * @return 如果找到，返回List<JT_UNIT_TREE_V> 如果没有找到，返回null
     * @throws DataAccessException
     */
	@SuppressWarnings({ "unused", "rawtypes", "unchecked" })
	@Override
	public List getSubUnit(String userId, String parentUnitID) throws Exception {
		List subTree = new ArrayList();
		HashMap paramMap = new HashMap();
		paramMap.put("userID", userId);
		paramMap.put("parentUnitID", parentUnitID);
		return subTree = dao.findList("selectSubUnit", paramMap);
	}

	/**
     * 方法简要描述信息.
     * <p>
     * 描述: 新建组织单元，包括（组织机构基本信息、上级岗位信息、人员信息）
     * </p>
     * <p>
     * 备注: 详见顺序图
     * </p>
     * 
     * @param unitVO
     *            - 含有人员列表的组织单元vo
     * @param extTableName
     *            - 扩展表名称
     * @param idColName
     *            - 扩展表id列名称
     * @throws DataAccessException
     */
	@Override
    public void createUnit(WF_ORG_UNIT unitVO, String extTableName, String idColName) throws Exception {

        // this.getSqlMapClient().insert("WF_ORG_UNIT.insert", unitVO);
        dao.insert("WF_ORG_UNIT_insert", unitVO);
        if (unitVO.getUnitUsersArray() != null) {
            for (int i = 0; i < unitVO.getUnitUsersArray().length; i++) {
                WF_ORG_USER_UNIT userUnitVO = new WF_ORG_USER_UNIT();
                userUnitVO.setUnitId(unitVO.getUnitId());
                userUnitVO.setUserId(unitVO.getUnitUsersArray()[i].toString());
                // userUnitVO.setUnitUsersArray(unitVO.getUnitUsersArray());
                // this.getSqlMapClient().insert("WF_ORG_UNIT.insertUserUnit",
                // userUnitVO);
                dao.insert("WF_ORG_UNIT_insertUserUnit", userUnitVO);
            }
        }
        // if (unitVO.getExtInfoMap() != null) {
        // Iterator columnIter = unitVO.getExtInfoMap().keySet().iterator();
        // int columnTotal = unitVO.getExtInfoMap().size();
        // String insertExtInfoString1 = "INSERT INTO " + extTableName + " (" +
        // idColName + ',';
        // String insertExtInfoString2 = " VALUES ('" + unitVO.getUnitId();
        // if (!columnIter.hasNext()) {
        // insertExtInfoString2 += "')";
        // } else {
        // insertExtInfoString2 += "','";
        // }
        // int j = 0;
        // while (columnIter.hasNext()) {
        // String columnName = columnIter.next().toString();
        // j++;
        // String columnValue = unitVO.getExtInfoMap().get(columnName) == null ?
        // ""
        // : unitVO.getExtInfoMap().get(columnName).toString();
        // // if(!columnValue.equals(""))
        // insertExtInfoString1 += columnName;
        // insertExtInfoString2 += columnValue;
        // if (columnTotal == j) {
        // insertExtInfoString1 += ")";
        // insertExtInfoString2 += "')";
        // } else {
        // insertExtInfoString1 += ",";
        // insertExtInfoString2 += "','";
        // }
        // }
        // System.out.println(insertExtInfoString1 + insertExtInfoString2);
        //// conn = this.getSqlMapClient().getDataSource().getConnection();
        // conn =
        // sqlSession.getConfiguration().getEnvironment().getDataSource().getConnection();
        // statement = conn.createStatement();
        // statement.execute(insertExtInfoString1 + insertExtInfoString2);
        // }
        // } catch (SQLException e) {
        // e.printStackTrace();
    }

	/**
     * 方法简要描述信息.
     * <p>
     * 描述: 修改组织单元，包括（组织机构基本信息、上级岗位信息、人员信息）
     * </p>
     * <p>
     * 备注: 详见顺序图
     * </p>
     * 
     * @param unitVO
     *            - 含有人员列表的组织单元vo
     * @param extTableName
     *            - 扩展表名称
     * @param idColName
     *            - 扩展表id列名称
     * @throws DataAccessException
     */
	@Override
    public void updateUnit(WF_ORG_UNIT unitVO, String extTableName, String idColName) throws Exception {

        dao.update("WF_ORG_UNIT_updateUnit", unitVO);
        
        // 2018-1-29 15:00:20 wxy 准备数据，处理用户缓存
        processCurrentUserCache(unitVO);
        // over
        
        dao.delete("WF_ORG_UNIT_deleteUserUnit", unitVO.getUnitId());
        if (unitVO.getUnitUsersArray() != null) {
            for (int i = 0; i < unitVO.getUnitUsersArray().length; i++) {
                WF_ORG_USER_UNIT userUnitVO = new WF_ORG_USER_UNIT();
                userUnitVO.setUnitId(unitVO.getUnitId());
                userUnitVO.setUserId(unitVO.getUnitUsersArray()[i].toString());
                dao.insert("WF_ORG_UNIT_insertUserUnit", userUnitVO);
            }
        }
        // if (unitVO.getExtInfoMap() != null) {
        // Iterator columnIter = unitVO.getExtInfoMap().keySet().iterator();
        // if (columnIter.hasNext()) {
        // int columnTotal = unitVO.getExtInfoMap().size();
        // String updateExtInfoString = "UPDATE " + extTableName + " SET ";
        // String whereClause = " WHERE " + idColName + " = '" +
        // unitVO.getUnitId() + "'";
        // int j = 0;
        // while (columnIter.hasNext()) {
        // String columnName = columnIter.next().toString();
        // j++;
        // String columnValue = unitVO.getExtInfoMap().get(columnName) == null ?
        // ""
        // : unitVO.getExtInfoMap().get(columnName).toString();
        // if (columnName.equalsIgnoreCase("id"))
        // continue;
        // updateExtInfoString += columnName + " = '" + columnValue + "'";
        // if (columnTotal > j) {
        // updateExtInfoString += ",";
        // }
        // }
        // System.out.println(updateExtInfoString + whereClause);
        //// conn = this.getSqlMapClient().getDataSource().getConnection();
        // conn =
        // sqlSession.getConfiguration().getEnvironment().getDataSource().getConnection();
        // statement = conn.createStatement();
        // statement.execute(updateExtInfoString + whereClause);
        // }
        // }
        // } catch (SQLException e) {
        // e.printStackTrace();
    }

	/**
	 * 2018-1-29 15:00:20 wxy 准备数据，处理用户缓存
	 * @param unitVO
	 * @throws Exception
	 */
    private void processCurrentUserCache(WF_ORG_UNIT unitVO) throws Exception {
        Map<String, String> reqParam = new HashMap<String, String>();
        reqParam.put("unitId", unitVO.getUnitId());
        
        // 变更以前的userIds
        List<String> origUserIds = new ArrayList<String>();
        // 变更以后的userIds
        List<String> tarUserIds = Arrays.asList(unitVO.getUnitUsersArray());
        
        List<Map> origUserList = dao.findList("WF_ORG_UNIT_selectUnitUsers", reqParam);
        if (origUserList != null) {
            for(Map aUser : origUserList) {
                origUserIds.add(aUser.get("USER_ID").toString());
            }
        }
        
        // 发生了变化的用户id列表
        List<String> affectUserIds = getDiffrent(origUserIds, tarUserIds);
        
        // 根据affectUserIds生成affectUserAccounts
        List<String> affectUserAccounts = new ArrayList<String>();
        for (String affectUserId : affectUserIds) {
            boolean founded = false;
            if (unitVO.getUserList() != null) {
                for(WF_ORG_USER tarUser : (List<WF_ORG_USER>)unitVO.getUserList()) {
                    if (affectUserId.equals(tarUser.getUserId())) {
                        affectUserAccounts.add(tarUser.getUserAccount());
                        founded = true;
                        break;
                    }
                }
            }
            // 在目标list上没有找到，那么就在源list上
            if (!founded && origUserList != null) {
                for(Map userMap : origUserList) {
                    String userId = userMap.get("USER_ACCOUNT").toString();
                    if (userId.equals(affectUserId)) {
                        affectUserAccounts.add(userId);
                        founded = true;
                        break;
                    }
                }
            }
        }
        
        // 事件定义
        AfterRBACChangedEvent event = new AfterRBACChangedEvent();
        event.setAffectUserIds(affectUserIds);
        event.setAffectUserAccounts(affectUserAccounts);
        
        // 事件处理器
        EventBusManager eventManager = cn.rkylin.apollo.common.util.BeanUtils.getBean("eventBusManager");
        
        // 激发事件
        eventManager.fireEvent(event);
    }

    /**
     * 方法简要描述信息.
     * <p>
     * 描述: 删除组织单元。如果组织单元下面有角色、人员、岗位，则该组织单元不能删除
     * </p>
     * <p>
     * 备注: 详见顺序图
     * </p>
     * 
     * @param unitID
     *            - 组织单元id
     * @param extTableName
     *            - 扩展表名称
     * @param idColumnName
     *            - 扩展表id列名称
     * @throws DataAccessException
     */
	@Override
    public void deleteUnit(String unitID, String extTableName, String idColumnName, boolean advanceDelete)
            throws Exception {
        WF_ORG_UNIT unitVO = new WF_ORG_UNIT();
        unitVO.setUnitId(unitID);
        // 如果是高级删除，则先删除组织管理角色和组织下的用户
        if (advanceDelete) {
            dao.delete("WF_ORG_UNIT_deleteUnitRoles", unitVO);
            dao.delete("WF_ORG_UNIT_deleteUnitUsers", unitVO);
        }
        // 再删除组织单元
        dao.delete("WF_ORG_UNIT_delete", unitVO);
        // String deleteSQL = "delete FROM " + extTableName + " WHERE " +
        // idColumnName + " = '" + unitID + "'";
        // conn =
        // sqlSession.getConfiguration().getEnvironment().getDataSource().getConnection();
        // stmt = conn.createStatement();
        // System.out.println(deleteSQL);
        // stmt.execute(deleteSQL);
    }

	/**
     * 方法简要描述信息.
     * <p>
     * 描述: 组织机构类型 查询时：DICT_TYPE='unittype'
     * </p>
     * <p>
     * 备注: 详见顺序图
     * </p>
     * 
     * @return 如果找到，返回ArrayList<WF_ORG_DICTIONARY> 如果没有找到，返回new ArrayList
     * @throws DataAccessException
     */
	@SuppressWarnings({ "rawtypes"})
	@Override
    public ArrayList getUnitType(String type) throws Exception {
        List unitType = new ArrayList();
        // String dictType = "unittype";
        // unitType =
        // getSqlMapClient().queryForList("WF_ORG_DICTIONARY.selectUnitType",
        // type);
        unitType = dao.findList("WF_ORG_DICTIONARY_selectUnitType", type);
        if (unitType == null) {
            unitType = new ArrayList();
        }
        return (ArrayList) unitType;
    }

    @Override
    public List getEntName() throws Exception {
        return dao.findAllList("ENTERPRISE_GETENTNAME", "");
    }

    /**
     * 快速找2个List中不同的部分（比retainAll快）
     * @param list1
     * @param list2
     * @return
     */
    private static List<String> getDiffrent(List<String> list1, List<String> list2) {
        List<String> diff = new ArrayList<String>();
        List<String> maxList = list1 == null ? new ArrayList<String>() : list1;
        List<String> minList = list2 == null ? new ArrayList<String>() : list2;
        if (list2.size() > list1.size()) {
            maxList = list2;
            minList = list1;
        }
        Map<String, Integer> map = new HashMap<String, Integer>(maxList.size());
        for (String string : maxList) {
            map.put(string, 1);
        }
        for (String string : minList) {
            if (map.get(string) != null) {
                map.put(string, 2);
                continue;
            }
            diff.add(string);
        }
        for (Map.Entry<String, Integer> entry : map.entrySet()) {
            if (entry.getValue() == 1) {
                diff.add(entry.getKey());
            }
        }
        return diff;
    } 
}
